package com.cmc.cloud.cmclink.doc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.cmc.cloud.cmclink.common.filter.enums.FilterCondition;
import com.cmc.cloud.cmclink.doc.constants.CommonConstants;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.LimitRuleErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.entity.LimitRuleDO;
import com.cmc.cloud.cmclink.doc.entity.RuleMatchItemCfgDO;
import com.cmc.cloud.cmclink.doc.mapper.LimitRuleMapper;
import com.cmc.cloud.cmclink.doc.mapper.RuleMatchItemCfgMapper;
import com.cmc.cloud.cmclink.doc.service.LimitAttatchItemService;
import com.cmc.cloud.cmclink.doc.service.LimitConfirmItemService;
import com.cmc.cloud.cmclink.doc.service.LimitRuleItemService;
import com.cmc.cloud.cmclink.doc.service.LimitRuleService;
import com.cmc.cloud.cmclink.doc.vo.limitattatchitemvo.LimitAttatchItemBaseVO;
import com.cmc.cloud.cmclink.doc.vo.limitconfirmitemvo.LimitConfirmItemBaseVO;
import com.cmc.cloud.cmclink.doc.vo.limitruleitemvo.LimitRuleItemRespVO;
import com.cmc.cloud.cmclink.doc.vo.limitrulevo.LimitRuleCreateReqVO;
import com.cmc.cloud.cmclink.doc.vo.limitrulevo.LimitRulePageReqVO;
import com.cmc.cloud.cmclink.doc.vo.limitrulevo.LimitRuleRespVO;
import com.cmc.cloud.cmclink.doc.vo.limitrulevo.LimitRuleUpdateReqVO;
import com.cmc.cloud.cmclink.doc.vo.rulematchitemcfg.RuleMatchItemCfgRespVO;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 禁接规则 Service 实现类
 *
 * @author 招商轮船-管理员
 */
@Service
@Validated
public class LimitRuleServiceImpl implements LimitRuleService {
    private static final String SPILT_DELIMITER = ";";
    @Resource
    private LimitRuleMapper limitRuleMapper;

    @Resource
    private RuleMatchItemCfgMapper ruleMatchItemCfgMapper;

    @Resource
    private LimitRuleItemService limitRuleItemService;

    @Resource
    private LimitConfirmItemService limitConfirmItemService;

    @Resource
    private LimitAttatchItemService limitAttatchItemService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createLimitRule(LimitRuleCreateReqVO createReqVO) {
        // 插入
        LimitRuleDO limitRule = BeanUtil.copyProperties(createReqVO, LimitRuleDO.class);
        limitRuleMapper.insert(limitRule);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateLimitRule(LimitRuleUpdateReqVO updateReqVO) {
        // 校验存在
        validateLimitRuleExists(updateReqVO.getId());
        // 更新
        LimitRuleDO updateObj = BeanUtil.copyProperties(updateReqVO, LimitRuleDO.class);
        limitRuleMapper.updateById(updateObj);
    }

    @Override
    public void deleteLimitRule(Long id) {
        // 校验存在
        validateLimitRuleExists(id);
        // 删除
        limitRuleMapper.deleteById(id);
    }

    private void validateLimitRuleExists(Long id) {
        if (limitRuleMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(LimitRuleErrorCodeConstants.LIMIT_RULE_NOT_EXISTS);
        }
    }

    @Override
    public LimitRuleDO getLimitRule(Long id) {
        return limitRuleMapper.selectById(id);
    }

    @Override
    public List<LimitRuleDO> getLimitRuleList(Collection<Long> ids) {
        return limitRuleMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<LimitRuleDO> getLimitRulePage(LimitRulePageReqVO reqVO) {
        LambdaQueryWrapperX<LimitRuleDO> queryWrapperX = new LambdaQueryWrapperX<LimitRuleDO>()
                .likeIfPresent(LimitRuleDO::getRuleName, reqVO.getRuleName())
                .eqIfPresent(LimitRuleDO::getRuleType, reqVO.getRuleType());
        if (ObjectUtils.isNotEmpty(reqVO.getEffictiveDate())) {
            queryWrapperX.le(LimitRuleDO::getEffictiveDate, reqVO.getEffictiveDate());
            queryWrapperX.ge(LimitRuleDO::getExpiringDate, reqVO.getEffictiveDate());
        }
        return limitRuleMapper.selectPage(reqVO, queryWrapperX);
    }

    @Override
    public List<LimitRuleRespVO> findLimitRule(LimitRulePageReqVO reqVO, String usePeriod) {
        LambdaQueryWrapperX<LimitRuleDO> queryWrapperX = new LambdaQueryWrapperX<LimitRuleDO>()
                .likeIfPresent(LimitRuleDO::getUsePeriod, usePeriod)
                .eq(LimitRuleDO::getEnable, true);
        return BeanUtil.copyToList(limitRuleMapper.selectList(queryWrapperX), LimitRuleRespVO.class);
    }

    @Override
    public void matchAttatchAndConfirmAndRuleItem(List<LimitRuleRespVO> limitList) {
        if (CollectionUtil.isEmpty(limitList)) {
            return;
        }
        List<Long> rulesIds = limitList.stream().map(e -> e.getId()).collect(Collectors.toList());
        List<LimitRuleItemRespVO> ruleItemList = limitRuleItemService.getLimitRuleItemByMainIds(rulesIds);
        List<LimitConfirmItemBaseVO> confirmItemList = limitConfirmItemService.getLimitConfirmItemByMainIds(rulesIds);
        List<LimitAttatchItemBaseVO> attatchItemList = limitAttatchItemService.getLimitAttatchItemByMainIds(rulesIds);

        Map<Long, LimitRuleItemRespVO> ruleItemMap = ruleItemList.stream().collect(Collectors.toMap(LimitRuleItemRespVO::getMainId, e -> e));
        Map<Long, List<LimitConfirmItemBaseVO>> confirmItemMap = confirmItemList.stream().collect(Collectors.groupingBy(LimitConfirmItemBaseVO::getMainId));
        Map<Long, List<LimitAttatchItemBaseVO>> attatchItemMap = attatchItemList.stream().collect(Collectors.groupingBy(LimitAttatchItemBaseVO::getMainId));
        // 拼接扩展信息
        limitList.forEach(e -> {
            e.setRuleItem(ruleItemMap.get(e.getId()));
            e.setConfirmItemList(confirmItemMap.get(e.getId()));
            e.setAttatchItemList(attatchItemMap.get(e.getId()));
        });


    }

    @Override
    public List<RuleMatchItemCfgRespVO> getMatchItemConfiguration(String usePeriod) {
        LambdaQueryWrapperX<RuleMatchItemCfgDO> queryWrapperX = new LambdaQueryWrapperX<RuleMatchItemCfgDO>();
        queryWrapperX.eq(RuleMatchItemCfgDO::getUsePeriod,usePeriod).eq(RuleMatchItemCfgDO::getDeleted,0);
        List<RuleMatchItemCfgDO> ruleMatchItemCfgDos = ruleMatchItemCfgMapper.selectList(queryWrapperX);
        if (!CollectionUtils.isEmpty(ruleMatchItemCfgDos)){
            List<RuleMatchItemCfgRespVO> ruleMatchItemCfgRespVos = BeanUtil.copyToList(ruleMatchItemCfgDos, RuleMatchItemCfgRespVO.class);
            ruleMatchItemCfgRespVos.forEach(r -> {
                String predicates = r.getPredicates();
                if (ObjectUtils.isNotEmpty(predicates)){
                    String[] predicatesSplit = predicates.split(SPILT_DELIMITER);
                    ArrayList<Map<String, String>> predicateMapList = new ArrayList<>();
                    r.setPredicateMapList(predicateMapList);
                    for (String s : predicatesSplit) {
                        HashMap<String, String> stringStringHashMap = new HashMap<>(CommonConstants.DEFAULT_MAP_COUNT);
                        stringStringHashMap.put(s, FilterCondition.valueOf(s).getDescriptionEn());
                        predicateMapList.add(stringStringHashMap);
                    }
                }
            });
            return ruleMatchItemCfgRespVos;
        }else {
            return null;
        }
    }
}
